#include "TextureRender2.h"
#include "base/SnImage.h"
#include "base/shader.h"
#include <memory>

namespace Sivin {
  TextureRender2::TextureRender2() {

    mVertexData = {
        //|---positon----|-----color-----|--texCoord--|
        {0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f},//右上
        {-0.5, 0.5, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f}, //左上
        {-0.5, -0.5, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f},//左下
        {0.5, -0.5, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f}};//右下

    mElementIndexArray = {0, 1, 2, // 第一个三角形
                          0, 2, 3};// 第二个三角形

    mShader = std::make_unique<Shader>("./../shader/texture/vert.vs", "./../shader/texture/frag.fs");
  }

  TextureRender2::~TextureRender2() {
  }

  void TextureRender2::onGLInit() {
    mShader->init();
    initVAO();
    initTexture();
  }

  void TextureRender2::onRender() {
    mShader->start();
    glBindTexture(GL_TEXTURE_2D, mTextureId);
    glBindVertexArray(mVAO);
    glDrawElements(GL_TRIANGLES, mElementIndexArray.size(), GL_UNSIGNED_INT, (void *) 0);
    mShader->end();
  }


  void TextureRender2::initVAO() {
    glGenVertexArrays(1, &mVAO);
    GLuint vbo, ebo;
    glGenBuffers(1, &vbo);
    glGenBuffers(1, &ebo);
    glBindVertexArray(mVAO);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * mElementIndexArray.size(),
                 mElementIndexArray.data(), GL_STATIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(SnVertex) * mVertexData.size(),
                 mVertexData.data(), GL_STATIC_DRAW);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(SnVertex), (void *) 0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(SnVertex), (void *) offsetof(SnVertex, color));
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(SnVertex), (void *) offsetof(SnVertex, textureCoord));

    glBindVertexArray(0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
  }

  void TextureRender2::initTexture() {

    glGenTextures(1, &mTextureId);
    glBindTexture(GL_TEXTURE_2D, mTextureId);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    auto image = SnImage::loadImage("./../res/catong.png");
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image->width(), image->height(), 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image->width(), image->height(), GL_RGB, GL_UNSIGNED_BYTE, image->data().get());
    glBindTexture(GL_TEXTURE_2D, 0);
  }
}// namespace Sivin